package com.irdstudio.efp.esb.api.rest.yed.repay;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.irdstudio.basic.framework.core.base.FrameworkService;
import com.irdstudio.basic.framework.core.constant.ESBConstant;
import com.irdstudio.basic.framework.core.constant.EsbRetCodeStandard;
import com.irdstudio.basic.framework.core.constant.SDicCertTypeEnum;
import com.irdstudio.basic.framework.core.exception.BizException;
import com.irdstudio.basic.framework.core.exception.ESBException;
import com.irdstudio.basic.framework.core.util.StringUtil;
import com.irdstudio.efp.cus.service.facade.CusIndivService;
import com.irdstudio.efp.cus.service.vo.CusIndivVO;
import com.irdstudio.efp.esb.api.common.EsbRespServiceBeanCreator;
import com.irdstudio.efp.esb.api.rest.yed.req.ReqRepayRecordYedTotalBean;
import com.irdstudio.efp.esb.api.rest.yed.resp.RepayDetailArray;
import com.irdstudio.efp.esb.api.rest.yed.resp.RespRepayRecordYedTotalBean;
import com.irdstudio.efp.esb.api.service.sed.SedCommonService;
import com.irdstudio.efp.esb.api.service.yed.YedRepayDetailTotalService;
import com.irdstudio.efp.esb.api.util.RepayTypeTransUtil;
import com.irdstudio.efp.esb.common.constant.EsbBizEnums;
import com.irdstudio.efp.esb.common.constant.EsbSysHeadEnums;
import com.irdstudio.efp.esb.common.constant.RespRetCode;
import com.irdstudio.efp.esb.common.server.req.EsbReqServiceBean;
import com.irdstudio.efp.esb.common.server.resp.EsbRespServiceBean;
import com.irdstudio.efp.esb.service.bo.req.hj.RepayInfoQueryTotalReqBean;
import com.irdstudio.efp.esb.service.bo.resp.hj.RepayInfoQueryTotalRespBean;
import com.irdstudio.efp.esb.service.facade.hj.RepayInfoQueryService;
import com.irdstudio.efp.loan.service.facade.AccLoanService;
import com.irdstudio.efp.loan.service.facade.LoanRepayDetailService;
import com.irdstudio.efp.loan.service.vo.AccLoanVO;
import com.irdstudio.efp.loan.service.vo.LoanRepayDetailVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 优e贷还款记录查询 调互金新增接口，解决查询效率问题
 *
 * @author liangcongming :2020/11/19 11:35
 * @version 0.1
 * @date 2020/11/19 11:35
 * @since 2020/11/19 11:35
 */
@RestController
@RequestMapping("/esb")
public class YedRepayRecordTotalController implements FrameworkService {
    private static Logger logger = LoggerFactory.getLogger(YedRepayRecordTotalController.class);

    @Autowired
    private SedCommonService<RespRepayRecordYedTotalBean> sedCommonService;

    @Autowired
    private YedRepayDetailTotalService yedRepayDetailTotalService;

    @Autowired
    @Qualifier("cusIndivService")
    private CusIndivService cusIndivService;

    @Autowired
    @Qualifier("loanRepayDetailService")
    private LoanRepayDetailService loanRepayDetailService;

    @Autowired
    private RepayInfoQueryService repayInfoQueryService;

    @Autowired
    private AccLoanService accLoanService;

    /**
     * 获取ESB请求对象，校验 ESB请求系统头和请求应用头对象
     *
     * @param request 请求对象集合
     * @return
     */
    @ModelAttribute("esbReqServiceBean")
    public EsbReqServiceBean getReqEsbHeadBean(HttpServletRequest request) {
        logger.info("校验 ESB请求系统头和请求应用头对象!");
        EsbReqServiceBean esbReqServiceBean = (EsbReqServiceBean) request.getAttribute("esbReqServiceBean");
        return esbReqServiceBean;
    }

    /**
     * 获取ESB请求对象，校验 ESB请求体对象
     *
     * @param request 请求对象集合
     * @return
     */
    @ModelAttribute("reqRepayRecordYedNewBean")
    public ReqRepayRecordYedTotalBean getReqEsbBodyBean(HttpServletRequest request) {
        logger.info("校验 ESB请求体对象！");
        String esbReqBody = (String) request.getAttribute("esbReqBody");
        return JSONObject.parseObject(esbReqBody, ReqRepayRecordYedTotalBean.class);
    }

    @PostMapping("/SERVICE_30230002_13")
    public EsbRespServiceBean doRecv(@Validated @ModelAttribute("esbReqServiceBean") EsbReqServiceBean esbReqServiceBean, BindingResult br1,
                                     @Validated @ModelAttribute("reqRepayRecordYedNewBean") ReqRepayRecordYedTotalBean reqRepayRecordYedTotalBean, BindingResult br2, Exception exception) throws ESBException {
        //全局流水
        String glblSrlNo = esbReqServiceBean.getSysHead().getGlblSrlNo();
        logger.info("【30230002_13】还款明细查询开始,全局流水号为：[{}]", glblSrlNo);
        //页码-当前查询第几页的数据
        int page = StringUtil.isNullorBank(reqRepayRecordYedTotalBean.getPageNo()) ? 1 : Integer.parseInt(reqRepayRecordYedTotalBean.getPageNo());
        //每页显示条数
        int pageSize = StringUtil.isNullorBank(reqRepayRecordYedTotalBean.getPageSize()) ? 10 : Integer.parseInt(reqRepayRecordYedTotalBean.getPageSize());
        //响应体
        RespRepayRecordYedTotalBean respRepayRecordYedTotalBean = new RespRepayRecordYedTotalBean();

        if (Objects.nonNull(exception)) {
            //如果异常不为空，那么处理异常返回信息
            return sedCommonService.getEsbRespServiceBeanByException(esbReqServiceBean, exception, respRepayRecordYedTotalBean, RespRetCode.FAILE, EsbRetCodeStandard.JKYDCSJYBTG);
        }

        try {
            //【第一步】根据证件号、证件类型、产品号查询借据信息
            AccLoanVO loanQueryParam = new AccLoanVO();
            loanQueryParam.setPrdCode(reqRepayRecordYedTotalBean.getPdNo());
            loanQueryParam.setCertCode(reqRepayRecordYedTotalBean.getIdCardNo());
            loanQueryParam.setCertType(SDicCertTypeEnum.IDCARD.getValue());
            List<AccLoanVO> accLoanVOList = accLoanService.queryByCertandPrd(loanQueryParam);

            //【第二步】根据借据号查询借据在网贷系统失败的还款明细
            List<String> loanNos = new ArrayList<String>();
            if (Objects.nonNull(accLoanVOList)) {
                logger.info("【30230002_13】查询到借据信息：" + accLoanVOList.size() + "条！");
                loanNos = accLoanVOList.stream().map(AccLoanVO::getBillNo).collect(Collectors.toList());
            }

            List<LoanRepayDetailVO> loanRepayDetailVOS = new ArrayList<LoanRepayDetailVO>();
            if (Objects.nonNull(loanNos) && !loanNos.isEmpty()) {
                loanRepayDetailVOS = loanRepayDetailService.queryFailedDataByLoanNos(loanNos);
            }
            if(Objects.nonNull(loanRepayDetailVOS)){
                logger.info("【30230002_13】查询到还款信息：" + loanRepayDetailVOS.size() + "条！");
            }

            // 【第三步】根据身份证查询互金客户号
            CusIndivVO cusIndivVO = new CusIndivVO();
            cusIndivVO.setCertType(SDicCertTypeEnum.IDCARD.getValue());
            cusIndivVO.setCertCode(reqRepayRecordYedTotalBean.getIdCardNo());
            cusIndivVO = cusIndivService.queryByCust(cusIndivVO);
            if (Objects.isNull(cusIndivVO) || StringUtil.isNullorBank(cusIndivVO.getInnerCusId())) {
                throw new BizException("根据证件号查询的客户号为空！");
            }
            //【第四步】根据互金客户号及产品类型查询互金的30230002_14还款明细
            RepayInfoQueryTotalReqBean hjReqBean = new RepayInfoQueryTotalReqBean();
            hjReqBean.setInnerCusId(cusIndivVO.getInnerCusId());
            hjReqBean.setPrdId(reqRepayRecordYedTotalBean.getPdNo());
            hjReqBean.setSetlTyp(RepayTypeTransUtil.transWd2Hj(reqRepayRecordYedTotalBean.getSetlType()));
            hjReqBean.setGlobaNo(glblSrlNo);
            RepayInfoQueryTotalRespBean repayInfoQueryTotalRespBean = repayInfoQueryService.applyRepayInfoQueryTotal(hjReqBean);
            if(Objects.isNull(repayInfoQueryTotalRespBean)){
                throw new BizException("互金接口查询异常！");
            }

            // 【第五步】整合处理互金响应体及网贷还款数据
            logger.info("【30230002_13】开始整合处理互金响应体及网贷还款数据...");
            List<RepayDetailArray> repayDetailArrs = new ArrayList<RepayDetailArray>();
            yedRepayDetailTotalService.handleResp(repayDetailArrs, loanRepayDetailVOS, repayInfoQueryTotalRespBean);

            // 【第六步】排序规则 还款号倒序
            logger.info("【30230002_13】数据整合完毕，开始排序...");
            List<RepayDetailArray> repayOrdered = repayDetailArrs.stream()
                    .sorted(Comparator.comparing(RepayDetailArray::getCreateTime).reversed())
                    .collect(Collectors.toList());

            //【第七步】分页截取，组装报文并返回
            logger.info("【30230002_13】排序完毕，开始分页...");
            List<RepayDetailArray> repaySubed = new ArrayList<RepayDetailArray>();

            int maxPage = repayOrdered.size() % pageSize == 0 ? repayOrdered.size() / pageSize : repayOrdered.size() / pageSize + 1;
            if (page > maxPage) {
                logger.info("当前页码已超过最大页，当前页面数据为空！");
            } else {
                int start = (page - 1) * pageSize;
                int end = page * pageSize;
                if (page * pageSize > repayOrdered.size()) {
                    end = repayOrdered.size();
                }
                repaySubed = repayOrdered.subList(start, end);
            }
            respRepayRecordYedTotalBean.setPageNo(reqRepayRecordYedTotalBean.getPageNo());
            respRepayRecordYedTotalBean.setPagSize(reqRepayRecordYedTotalBean.getPageSize());
            respRepayRecordYedTotalBean.setTotalSize(repayDetailArrs.size() <= 0 ? "0" : String.valueOf(repayDetailArrs.size()));
            respRepayRecordYedTotalBean.setRepayDetailArr(repaySubed);
            respRepayRecordYedTotalBean.setRetCd(ESBConstant.SUCCESS);
            respRepayRecordYedTotalBean.setRetMsg("查询成功");

            logger.info("【30230002_13】还款明细查询结束,全局流水号为：[{}]", glblSrlNo);
            //返回报文
            return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean,
                    JSONObject.toJSONString(respRepayRecordYedTotalBean, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty, SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteNullNumberAsZero, SerializerFeature.WriteMapNullValue),
                    EsbSysHeadEnums.RetStEnum.SUCCESS.getCode(),
                    EsbBizEnums.RetCodeEnum.SUCCESS.getVALUE(),
                    "查询成功");
        } catch (Exception ex) {
            logger.error("还款明细接口出现异常，异常信息为：", ex);
            return sedCommonService.getEsbRespServiceBeanByException(esbReqServiceBean, ex, respRepayRecordYedTotalBean, RespRetCode.FAILE, EsbRetCodeStandard.SJCLYC);
        }
    }


}
